package extended

import "jvmgo/ch09/instructions/base"
import "jvmgo/ch09/instructions/loads"
import "jvmgo/ch09/instructions/math"
import "jvmgo/ch09/instructions/stores"
import "jvmgo/ch09/rtda"

// 通过加长的byte拓展局部变量表
type WIDE struct {
    modifiedInstruction base.Instruction
}

func (self *WIDE) FetchOperands(reader *base.BytecodeReader) {
    opcode := reader.ReadUint8()
    switch opcode {
    case 0x15:
        inst := &loads.ILOAD{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x16:
        inst := &loads.LLOAD{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x17:
        inst := &loads.FLOAD{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x18:
        inst := &loads.DLOAD{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x19:
        inst := &loads.ALOAD{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x36:
        inst := &stores.ISTORE{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x37:
        inst := &stores.LSTORE{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x38:
        inst := &stores.FSTORE{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x39:
        inst := &stores.DSTORE{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x3a:
        inst := &stores.ASTORE{}
        inst.Index = uint(reader.ReadUint16())
        self.modifiedInstruction = inst
    case 0x84:
        inst := &math.IINC{}
        inst.Index = uint(reader.ReadUint16())
        inst.Const = int32(reader.ReadInt16())
        self.modifiedInstruction = inst
    case 0xa9: // ret
        panic("Unsupported opcode: 0xa9!")
    }
}

func (self *WIDE) Execute(frame *rtda.Frame) {
    self.modifiedInstruction.Execute(frame)
}
